본문으로 건너뛰기

오늘한 일

  • Rust 공부
  • Android Calendar UI 구현중
  • Flutter 웹뷰 프로젝트 공유방법 알아보기

⇒ 총 6타임.. 1타임은 이모가 집에 방문한 관계로 실패


Rust 강의

Traits

:함수의 표준화에 사용 like interface,
Struct에 귀속되는 정보

//Trait 명시단계
trait Noise{
//함수를 정의만 해놓은 상태
//추가적인 명시가 필요 (like override)
fn make_noise(&self);
}

//명시된 Trait를 Struct에서 구체화하는 단계
struct Person;
//impl Trait for Struct 구조
impl Noise for Person{
fn make_noise(&self){
println!("hello");
}
}

//Trait 사용을 위한 정의단계
fn hello(noisy: impl Noise){
noisy.make_noise();
}

//Trait 최종 호출단계
hello(Person{});


if let

: match only 1 case / 나머지 case는 버림
in Option<>

if let 비굣값 = 변수값{
//변수값이 비교대상이 되는 값과 동일할 때만 실행된다.
}


while let

while let 비굣값 = 변수값{
//let 비굣값 = 변수값이 참인 경우에만 실행
}

의문점, let A = B 자체가 조건식이 아닌가

/* 컴파일 에러 - expected expression, found let statement
fn main() {
let A = 10;
let B = 10;

println!("{:?}", let A = B);
}
*/

→ 아니다. let A=B를 bool 값으로 반환하지 못했다.
if let, while let이 특수한 사용인 것으로…

다만 let A = B 문을 statement로는 인식한 모습을 볼 수 있었다.


while let 용례

fn main(){
let lists = vec![1, 2, 3, 4, 5];
let mut lists_iter = lists.iter();

while let Some(num) = lists_iter.next() {
println!("{:?}", num);
}
}


외부 Crate 사용법

cargo.toml 프로젝트 설정, 관리 파일
cargo.lock 의존 라이브러리 & 버전 추적


Crate 접근 방법

공식사이트: https://crates.io/
비공식사이트: https://lib.rs/
→ extract 확인



Default Trait

: 기본생성자와 비슷함

//패키지선언
struct Package{
weight: f64
}
//Default 명시
impl Default for Package{
//default()만을 함수로 가지고 있음
fn default() -> Self{ weight: 32.0 }
}

//default 호출
fn main(){
let pack1 = Package::default();
}

→ 입력값을 필요로 하지 않고 구조체를 만드는 상황
== 구조체의 기본값(default)를 설정하는 경우 유용하게 사용됨



리터럴 값 관리 - const

const MAX_SPEED: i32 = 9000



다른 파일의 Crate 사용

**//Cargo.toml 파일**

[lib]
name = "NAME"
path = "src/lib.rs"

→ Name으로 경로에 접근가능


**// src/lib.rs 파일**

pub fn print_lib(){}

→ 디폴트는 private 이므로 다른 파일 사용을 위해 pub 키워드 사용


//사용할 메인이 되는 파일

use NAME::print_lib;
mod math;

use 로 사용
mod같은 디렉토리 내 다른 파일을 module로 명시한다고 컴파일러가 인식



모듈 추가 정보들

여러 개의 함수 사용하기

**use A::{B,C}**
= A의 B와 C를 사용하겠다는 것 의미, 집합이다. 순서는 상관없다.


모듈 그룹만들기

**mod.rs** 파일 포함 → 다른 모듈파일 관리
모듈 그룹 폴더명으로 불러올 수도 있음



Custom Error

: 비슷하게 동작하는 동작에 모두 적용가능

예시

use thiserror::Error;

#[derive(Debug, Error)]
enum LoginError{
#[error("database error")]
DatabaseError(#[from] Sqlerror),

#[error("user not found")]
UserNotFound,

...

}

// =>
fn login() -> Result<String, LoginError>{}

use thiserror::Error;
: thiserror라는 crate 사용

#[derive(Debug, Error)]
: Enum에서 에러를 정의해주기 전에 derive로 용도 명시

#[error("database error")]
: database error로 에러를 정의

CustomError(#[from] OTHER_ERR_TYPE)
: 기존의 에러를 #[from] 키워드를 사용해서 나만의 에러로



New Type 개념

: Struct() 를 사용
⇒ Tuple 형태의 구조체를 사용하게된다.

컴파일타임에서 에러를 찾아낼 수 있다..는
장점이 이해가 안돼서 공식페이지 예제를 긁어왔다.

struct Years(i64);
struct Days(i64);

impl Years {
pub fn to_days(&self) -> Days {
Days(self.0 * 365)
}
}
impl Days {
/// truncates partial years
pub fn to_years(&self) -> Years {
Years(self.0 / 365)
}
}

⇒ 여전히 이해는 안된다.


왜 굳이 self.{field}를 안쓰고 튜플형태를 써서 self.0 으로 다루는걸까
→ 공식문서 읽을 때 나오면 더 자세히 보기로 했다.



메모리 지식

복습) Address → Physical 공간 // Offset → 물리적, 인접 공간


Stack 순차적 할당 (빠른 할당)

접근을 위해 Address + Offset 사용


Heap

알고리즘적 할당 (느린 할당)

접근을 위해 포인터 사용 (중간 값도 빠르게 접근)

:: vector, hashmap


포인터 다루기

let IN_HEAP :Box<struct> = Box::new(yes);


포인터 데이터 접근

let IN_STACK = *IN_HEAP




///////////////////////////////////////////////////////////




Android 구현 이슈

RecyclerView 초기화 방법

val recyclerView: RecyclerView = findViewById(R.id.recyclerView);
val adapter: MyAdapter = new MyAdapter(dataList);

recyclerView.setAdapter(adapter);

RecyclerView 리소스를 불러와 저장
adapter 로 리스트 관리 (초기화)
RecyclerView 에 초기화 된 리스트 전달, 화면에 띄움



디자인 → UI 구현

스크린샷 2023-07-07 오후 2 43 15: OX Linear한 배치
  1. 시간탭 여부 (아침/점심/저녁/자기전)
  2. 각 상황별 OX 여부

[1] Column으로 관리

  • [아침, 점심, 저녁, 자기전] 존재하는지 확인하는 탭
  • 존재하면 Column으로 생성
  • 존재하면 최근 4개 data(0, O, X 확인)
  • 오늘/어제/2일전/3일전/4일전/5일전은 고정으로 배치해도 될 듯

...._.. 갈피를 놓쳤다.


불필요한 부분은 아예 보이지 않게 처리하고 싶은 상황임을 고려
→ TableLayout은 동적으로 Column을 지울 수 없기 때문에 부적합


과정 정리

4개의 리스트를 확인한다 (아침 점심 저녁 자기전)
리스트가 비어있다면 LinearLayout(vertical)에 동적으로 기입하지 않는다.
리스트가 비어있지 않다면 LinearLayout(vertical)에 동적으로 기입한다.


LinearLayout(horizontal)의 gravity는 중간으로 맞춘다.
LinearLayout(horizontal)의 크기는 패널크기에 맞춘다.


일자(오늘 어제 2일전…) 의 내용은 LinearLayout(Vertical)의 요소별 마진(dp단위)과 똑같이 맞춘다.
일자는 패널 좌측에 붙게 설정한다.




///////////////////////////////////////////////////////////




웹뷰 앱링크 알아보기

개념들

딥링크: 특정 콘텐츠에 직접 도달하는 모든 링크를 뜻
== 일상적으로 사용하는 것들!

https://naver/example.com 를 쳐서 들어갈 때,
https://naver/https://naver/example.com 이런 식으로 들어가지 않잖아

바로 저 deep한 URI로 바로 접속하는 가능하게 하는 링크를 “딥”링크라고 한다.


URI scheme

URI: Uniform Resource Identifier → 리소스를 가리킨다
schemem: http:// https://와 같은 것을 의미한다.

이러한 모든 것들은 요구되는 콘텐츠 유형을 나타내며 모바일 앱은 자신만의 맞춤 URI 스킴을 등록할 수 있다고한다. 따라서 hakrim://와 같이도 만들 수 있다.

but.. 앱이 설치되지 않은 경우 문제가 생긴다.
앱이 설치되지 않은 경우 해당 scheme으로 이동이 불가하며 에러메시지를 띄우는 것 밖에 하지 못한다.


앱링크: 앱 고유 콘텐츠 유형의 URI 스킴과 달리 앱 링크는 앱 내부의 특정 콘텐츠를 가리키는 표준 웹링크이다.
= 바로 지금 필요한 것



딥링크 구현법

작업을 순서대로 시도한다.

  1. URI를 처리할 수 있는, 사용자가 선호하는 앱(지정되어 있는 경우)을 엽니다.
  2. URI를 처리할 수 있는, 사용 가능한 유일한 앱을 엽니다.
  3. 사용자가 대화상자에서 앱을 선택하도록 합니다.

안드로이드 Manifest에 정의할 내용

<intent-filter android:label="@string/filter_view_http_gizmos">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<!-- Accepts URIs that begin with "http://www.example.com/gizmos” -->
<data android:scheme="http"
android:host="www.example.com"
android:pathPrefix="/gizmos" />
<!-- note that the leading "/" is required for pathPrefix-->
</intent-filter>
<intent-filter android:label="@string/filter_view_example_gizmos">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<!-- Accepts URIs that begin with "example://gizmos” -->
<data android:scheme="example"
android:host="gizmos" />
</intent-filter>

플랫폼 구분

안드로이드 →

iOS → …

!!!보다보니 내가 원하는 방향이 아님을 알 수 있었다.

원하는 건 아니었지만 웹뷰의 기저도 딥링크로 구성되어 있다는 점을 간단하게 알아볼 수 있어서 신기했다.


⇒ 나는 포괄적인 딥링크로 웹페이지에 접속하는 것을 원하는 게 아니라 앱링크로 앱을 열 수 있는 프로그램을 원한다


[방법1] React 라이브러리 활용, 프론트 쪽에서 바로 ‘앱으로 공유’를 위한 탭 생성

https://www.npmjs.com/package/react-web-share


[방법2] Flutter 라이브러리 활용,

프론트 → 모바일 통신으로 앱 공유를 하겠다는 정보를 수신하면

앱링크를 통해 해당 앱을 열기

https://pub.dev/packages/uni_links